/*
Hermes Core: General Purpose Mobile Agent Platform
Copyright (C) 2006 UNICAM - Università degli Studi di Camerino

Group leaders: Flavio Corradini and Emanuela Merelli

Developers: Ezio Bartocci, Diego Bonura, Rosario Culmone,
Davide Lorenzoli, Leonardo Mariani, Francesca Piersigilli, 
Lorenzo Scortichini, Leonardo Vito.

GNU Lesser Public License

This library is free software; you can redistribute it 
and/or modify it under the terms of the GNU Lesser General 
Public License as published by the Free Software Foundation, 
version 2.1 of the License.

This library is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU Library General Public License for more details.

You should have received a copy of the GNU Library General Public 
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.

Emanuela Merelli
Dipartimento di Matematica ed Informatica
Università di Camerino
via Madonna delle Carceri, 62032 Camerino, Italy
E.Mail: emanuela.merelli@unicam.it
*/
package hermesV2.basicServices.communication;

import hermesV2.Message;

import hermesV2.agent.Identificator;


/**
 * This is the interface of the communication component that offers to the
 * agent layer a way to register agent into the component and to receive new
 * messages.
 *
 * @author Diego Bonura
 * @author Ezio Bartocci
 * @param <T>
 */
public interface Receive {
    /**
     * This method allows agents to be registered into the component.
     *
     * @param agentId The identificator of the agent that wants to receive
     *        messages.
     */
    public void setAgentReception(Identificator agentId);
    /**
     * Every agent wants to receive message must register it self into the
     * communication component. This method permits to register an agent to the
     * component and to restore old message queue associated to the right agent
     * identificator. After the registration new messages could be stored into
     * the old queue.
     * 
     * @param agentId
     *            The identificator of the agent that wants to receive messages.
     * @param vq The old message queue agent.
     */
    public void setAgentReception(Identificator agentId, MessageQueue<Message <?>>  vq);

    /**
     * This method permits to erase the registration of an agent into the
     * communication component.
     *
     * @param agentId The indentificator of the agent that dosen't want to
     *        receive messages anymore.
     */
    public void removeAgentReception(Identificator agentId);
    
    /**
     * Returns the queue associated to an agent identificator. It
     * check first if the agent is already registered (not yet now:after it checks if no
     * messages are waiting to be received from the agent and) then it gets the
     * vectoer queue from the receptionHashtable.
     * 
     * @param agentId
     *            The identificator of the agent.
     * @return The agent message queue;
     */
    public MessageQueue<Message <?>>  getAgentMessageQueue(Identificator agentId);

    /**
     * Returns the first message waiting into the blocking queue associated
     * with the identificator of the agent registered. If no messages are
     * present into the queue the caller will wait a new messages. If the
     * agent is not registered into the component this method returns null.
     *
     * @param agentId The identificator of the agent that wants to receive a
     *        message.
     *
     * @return The message waiting or null if the agent is not registered.
     */
    public  Message<?> getMessageSynch(Identificator agentId);
    
    /**
     * Returns the message with a specific sender waiting into the blocking queue associated
     * with the identificator of the agent registered. If no messages are
     * present into the queue the caller will wait a new messages. If the
     * agent is not registered into the component this method returns null.
     * @param <T>
     *
     * @param agentId The identificator of the agent that wants to receive a
     *        message.
     * @param senderId The identificator of the sender agent that it has to search into the
     *  messages queue.
     *
     * @return The message waiting or null if the agent is not registered.
     */
    public Message<?> getMessageSynch(Identificator agentId,Identificator senderId);
    
    /**
     * Returns the message with a specific sender name waiting into the blocking queue associated
     * with the identificator of the agent registered. If no messages are
     * present into the queue the caller will wait a new messages. If the
     * agent is not registered into the component this method returns null.
     *
     * @param agentId The identificator of the agent that wants to receive a
     *        message.
     * @param senderName The name of the sender agent that it has to search into the
     *  messages queue.
     *
     * @return The message waiting or null if the agent is not registered.
     */
    public  Message<?> getMessageSynch(Identificator agentId,String senderName);


    /**
     * Returns the first message waiting into the blocking queue associated
     * with the identificator of the agent registered. If no messages are
     * present into the queue it returns null. If the agent is not registered
     * into the component this method returns null.
     *
     * @param agentId The identificator of the agent that wants to receive a
     *        message.
     *
     * @return The message waiting or null if the agent is not registered.
     */
    public  Message<?>  getMessageAsynch(Identificator agentId);
    
    /**
     * Returns the first message waiting into the blocking queue associated
     * with the identificator of the agent registered. If no messages are
     * present into the queue it returns null. If the agent is not registered
     * into the component this method returns null.
     *
     * @param agentId The identificator of the agent that wants to receive a
     *        message.
     * @param senderId The identificator of the sender agent that it has to search into the
     *  messages queue.
     * @return The message waiting or null if the agent is not registered.
     */
    public Message<?> getMessageAsynch(Identificator agentId,Identificator senderId);
    
    /**
     * Returns the first message waiting into the blocking queue associated
     * with the identificator of the agent registered. If no messages are
     * present into the queue it returns null. If the agent is not registered
     * into the component this method returns null.
     *
     * @param agentId The identificator of the agent that wants to receive a
     *        message.
     * @param senderName The name of the sender agent that it has to search into the
     *  messages queue.
     * @return The message waiting or null if the agent is not registered.
     */
    public Message<?>  getMessageAsynch(Identificator agentId,String senderName);

    /**
     * Checks if an agent wants or not receive messages.
     *
     * @param agentId The identificator of the agent to check.
     *
     * @return True if the agent is registered false otherwise.
     */
    public boolean isAgentRegistered(Identificator agentId);
    
	/**
	 * Returns the first message waiting into the blocking queue associated with
	 * the identificator of the agent registered. If no messages are present
	 * into the queue it returns null. If the agent is not registered into the
	 * component this method returns null.
	 * 
	 * @param agentId
	 *            The identificator of the agent that wants to receive a
	 *            message.
	 * @param senderNames
	 *            The array of names of the sender agent that it has to search
	 *            into the messages queue.
	 * 
	 * @return The message waiting or null if the agent is not registered.
	 */
	public  Message<?>  getMessageAsynch(Identificator agentId,
			String[] senderNames);
	
	/**
	 * Returns the first message waiting into the blocking queue associated with
	 * of the identificator of the agent registered. If no messages are present
	 * into the queue the caller will wait a new messages. If the agent is not
	 * registered into the component this method returns null.
	 * 
	 * @param agentId
	 *            The identificator of the agent that wants to receive a
	 *            message.
	 * 
	 * @param senderNames
	 *            The array of names of the sender agent that it has to search
	 *            into the messages queue.
	 * 
	 * @return The message waiting or null if the agent is not registered.
	 */
	public  Message<?>  getMessageSynch(Identificator agentId, String[] senderNames);
	
    /**
     * Returns the message with a specific sender waiting into the blocking queue associated
     * with the identificator of the agent registered. If no messages are
     * present into the queue the caller will wait a new messages. If the
     * agent is not registered into the component this method returns null.
     *
     * @param agentId The identificator of the agent that wants to receive a
     *        message.
     * @param senderIds The array of identificators of sender agents that it has to search into the
     *  messages queue.
     *
     * @return The message waiting or null if the agent is not registered.
     */
    public Message<?>  getMessageSynch(Identificator agentId,Identificator[] senderIds);
    
    /**
     * Returns the first message waiting into the blocking queue associated
     * with the identificator of the agent registered. If no messages are
     * present into the queue it returns null. If the agent is not registered
     * into the component this method returns null.
     *
     * @param agentId The identificator of the agent that wants to receive a
     *        message.
     * @param senderIds The array of identificators of sender agents that it has to search into the
     *  messages queue.
    * @return The message waiting or null if the agent is not registered.
     */
    public Message<?>  getMessageAsynch(Identificator agentId,Identificator[] senderIds);
}
